import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow.keras.metrics
from keras_preprocessing.image import ImageDataGenerator
from numpy import float32
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
from sklearn.preprocessing import LabelEncoder
from tensorflow.core.protobuf.config_pb2 import ConfigProto
from tensorflow.keras.models import load_model
from tensorflow.python.client.session import Session
import tensorflow as tf

config = ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.5  #占用85%显存
session = Session(config=config)

data = pd.read_csv('submission.csv',header=None)
data =data.values
# 测试集数据
y = data[1:3470,1]
#将y_test标签字符串转换成int类型整数
le = LabelEncoder()
y_test = le.fit_transform(y)

model = load_model('D:\PyCharm_workplace\Test\saved_model\my_model02.h5')

img_rows, img_cols = 256, 256
batch_size = 100
test_loc = 'input/paddy-disease-classification/test_images'
test_data = ImageDataGenerator(rescale=1.0/255).flow_from_directory(
    directory=test_loc,
    target_size=(img_rows, img_cols),
    batch_size=batch_size,
    classes=['.'],
    shuffle=False,
)
#打印精确率和准确率以及召回率
evaluate_test = model.evaluate(test_data, verbose=1)
print("\nAccuracy =", "{:.7f}%".format(evaluate_test[1]*100))
print("Loss     =" ,"{:.9f}".format(evaluate_test[0]))

y_pred = model.predict(test_data)
print(y_pred)
# np.argmax()是numpy中获取array的某一个维度中数值最大的那个元素的索引
# axis=1指定代表我要查找的最大元素在第1维中的索引值
y_predict_max = np.argmax(y_pred,axis=1)    # 转换为预测标签

aug_gens = ImageDataGenerator(
    rescale=1.0/255.0,
    featurewise_center=False,
    samplewise_center=False,
    featurewise_std_normalization=False,
    samplewise_std_normalization=False,
    zca_whitening=False,
    validation_split=0.1,
    rotation_range=10,
    shear_range=0.25,
    zoom_range=0.1,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True,
    vertical_flip=True,
)

train_loc = 'input/paddy-disease-classification/train_images/'
train_data = aug_gens.flow_from_directory(
    train_loc,
    subset="training",
    seed=2,
    target_size=(img_rows, img_cols),
    batch_size=batch_size,
    class_mode="categorical")

inverse_map = {v:k for k,v in train_data.class_indices.items()}

acc = tensorflow.keras.metrics.SparseCategoricalAccuracy()(y_test,y_pred)
print('准确率：'+acc)
print('测试集的准确率Accuracy：', accuracy_score(y_test, y_predict_max))
print('精确度Precision:', precision_score(y_test, y_predict_max, average='micro'))
print('召回率Recall:', recall_score(y_test, y_predict_max, average='micro')
# 混淆矩阵
cm = confusion_matrix(y_test,y_predict_max)
print(cm)
#显示混淆矩阵图片
cm_display = ConfusionMatrixDisplay(cm).plot()
plt.show()

#规范化图片大小和像素值
def get_inputs(src=[]):
     pre_x = []
     for s in src:
         input = cv2.imread(s)  #读取图像
         input = cv2.resize(input, (32, 32))  #图像缩放函数
         input = cv2.cvtColor(input, (3))   #颜色空间转换函数  input是需要转换的图片   （3）是转换何种格式
         pre_x.append(input)  # input一张图片
     pre_x = np.array(pre_x) / 255.0  #归一化
    return pre_x
#要预测的图片保存在这里
predict_dir = '.\\'+input("请输入要预测的图片的路径:")#这里写随机一张图片的路径
# predict_dir= r"D:\PyCharm_workplace\Test\input\paddy-disease-classification\test_images\200001.jpg"#路径
test = os.listdir(predict_dir)
#打印后：['ship', 'truck']
print(test)
#新建一个列表保存预测图片的地址
images = []
#获取每张图片的地址，并保存在列表images中
for testpath in test:  #循环获取测试路径底下需要测试的图片
    for fn in os.listdir(os.path.join(predict_dir, testpath)):
        if fn.endswith('jpg'):
            fd = os.path.join(predict_dir, testpath, fn)
            print(fd)
            images.append(fd)
#调用函数，规范化图片
plt.imshow(images);
pre_x = get_inputs(images)
#预测
pre_y = model.predict(pre_x);
print(pre_y);
print(np.argmax(model.predict(pre_x),axis=1));



